﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NGinnBPM.Rules.TableDriven;
using System.IO;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;

namespace NGinnBPM.Rules
{
    
    public class TestCase
    {
        public string Id { get; set; }

        public JObject Input { get; set; }

        public string ExpectedRule { get; set; }

        public JObject ExpectedOutput { get; set; }
    }

    public class TestSet
    {
        public string RulesetName { get; set; }

        public List<TestCase> Tests { get; set; }

        private static JsonSerializer GetJsonSerializer()
        {
            JsonSerializerSettings s = new JsonSerializerSettings();
            return JsonSerializer.Create(s);
        }

        public string ToJsonString()
        {
            StringWriter sw = new StringWriter();
            GetJsonSerializer().Serialize(sw, this);
            return sw.ToString();
        }

        public static TestSet FromJsonString(string s)
        {
            JsonReader jsr = new JsonTextReader(new StringReader(s));
            return GetJsonSerializer().Deserialize<TestSet>(jsr);
        }
    }

    public class TestCaseResults
    {
        public TestCaseResults()
        {
            Messages = new List<string>();
        }

        public string CaseId { get; set; }
        public string RuleFired { get; set; }
        public List<string> Messages { get; set; }
    }
    /// <summary>
    /// class for testing rule sets
    /// </summary>
    public class RulesTester
    {
        public string BaseDirectory { get; set; }

        public void TestRuleset(RulesetDef ruleset, TestSet tests)
        {
            RuleScriptGenerator rsg = new RuleScriptGenerator();
            RuleEngine re = new RuleEngine();
            re.BaseDirectory = BaseDirectory;
            string fileName = ruleset.Name + ".boo";
            rsg.GenerateScript(ruleset, Path.Combine(BaseDirectory, fileName));
        }

        public List<TestCaseResults> TestTableRuleset(TestSet tests)
        {
            List<TestCaseResults> lst = new List<TestCaseResults>();
            TableDrivenRuleEngine tre = new TableDrivenRuleEngine();
            tre.BaseDirectory = this.BaseDirectory;
            foreach (TestCase tc in tests.Tests)
            {
                DynObject input = DynObject.FromJObject(tc.Input);
                DynObject output = new DynObject();

                tre.EvalRules(tests.RulesetName, input, output);

                DynObject expected = DynObject.FromJObject(tc.ExpectedOutput);
                foreach (string field in expected.GetFieldNames())
                {
                    object actualVal = output.Get(field);
                    object expectedVal = expected.Get(field);

                    if (!object.Equals(actualVal, expectedVal))
                    {
                    }
                }
            }
            return lst;
        }

        
        
    }
}
